package com.smartao.base.acl;

import java.util.List;
import java.util.Set;

import com.smartao.base.employee.Employee;
import com.smartao.base.position.Position;
import com.smartao.base.role.Role;
import com.smartao.core.orm.entity.BaseEntity;

/**
 * 访问控制列表
 * TODO Acl类存在的意义在于以Acl为单位做查询和缓存
 * @author sunxing
 */
public class Acl<T extends BaseEntity<T>> {
	private T entity;
	private List<AccessEntry> entries;

	// 明确构造参数，以防止非法构造Acl；
	public Acl(T entity, List<AccessEntry> entries) {
		this.entity = entity;
		this.entries = entries;
	}

	public T getEntity() {
		return entity;
	}

	public void setEntity(T entity) {
		this.entity = entity;
	}

	public List<AccessEntry> getEntries() {
		return entries;
	}

	public void setEntries(List<AccessEntry> entries) {
		this.entries = entries;
	}

	//TODO 
	public boolean isGranted(Employee employee, Permission permission) {
		
		for (AccessEntry entry : entries) {
			Long sid = null;
			// 匹配用户id
			if (entry.getEntryType().equals(EntryType.user)) {
				sid = employee.getId();
				if(checkSingleEntryPermission(sid, permission, entry)){
					return true;
				}
			}
			// 匹配角色
			else if (entry.getEntryType().equals(EntryType.role)) {
				Set<Role> roles = employee.getRoles();
				for(Role role : roles){
					if(checkSingleEntryPermission(role.getId(), permission, entry)){
						return true;
					}
				}
			}
			// 匹配部门
			else if(entry.getEntryType().equals(EntryType.department)){
				//TODO 是否要考虑父部门
				if(checkSingleEntryPermission(employee.getDepartment().getId(), permission, entry)){
					return true;
				}
			}
			// 匹配岗位
			else if(entry.getEntryType().equals(EntryType.position)){
				Set<Position> positions = employee.getPositions();
				for(Position position : positions){
					if(checkSingleEntryPermission(position.getId(), permission, entry)){
						return true;
					}
				}
			}
			// 匹配安全级别
			else if(entry.getEntryType().equals(EntryType.secLevel)){
				Long secLevel = employee.getSecLevel();
				if(secLevel>=entry.getSid() && checkSingleEntryPermission(entry.getSid(), permission, entry)){
					return true;
				}
			}
		}
		return false;
	}
	
	public boolean isGranted(List<Long> sids, Permission permission){
		for (AccessEntry entry : entries) {
			for(Long sid : sids){
				if(checkSingleEntryPermission(sid, permission, entry)){
					return true;
				}
			}
		}
		return false;
	}

	private boolean checkSingleEntryPermission(Long sid, Permission permission, AccessEntry entry) {
		if ((entry.getSid().equals(sid) && (entry.getMask() & permission.getMask()) != 0)) {
			return true;
		}
		return false;
	}

}
